package me.softwareengineer.guice.rendering.domain;

import java.util.List;
import java.util.Map;

import me.softwareengineer.guice.rendering.listener.EndHeaderEvent;
import me.softwareengineer.guice.rendering.listener.Listener;
import me.softwareengineer.guice.rendering.listener.StartHeaderEvent;

/**
 * Represents a header in a {@link DOM} tree.
 * <p>
 * This class generates the following events:
 * <ul>
 * 	<li>{@link StartHeaderEvent}</li>
 * 	<li>{@link EndHeaderEvent} </li>
 * </ul>
 * </p>
 * 
 * 
 * <pre>
 * This class is thread-safe and can be cached/re-used and used concurrently.
 * </pre>
 * 
 * @author yad.tahir
 * @since 1.0
 * @see StartHeaderEvent 
 * @see EndHeaderEvent
 */

//This class is marked as final since we want to make immutable as much as possible.
public final class HeaderElement extends Element {
	/**
	 * The level of the header.
	 */
	private final HeaderLevel level;
	
	/**
	 * Creates a header element without properties
	 * 
	 * @param children
	 *            the children of the element
	 * @param headerLevel
	 *            the level of the header element. For more information, see
	 *            {@link HeaderLevel}
	 */
	public HeaderElement(List<Element> children, HeaderLevel headerLevel) {
		super(children);
		this.level = headerLevel;
	}

	/**
	 * Create a header element with the provided properties
	 * 
	 * @param children
	 *            the sub element of the current element
	 * @param headerLevel
	 *            the level of the header element. For more information, see
	 *            {@link HeaderLevel}
	 * @param properties
	 *            the properties of the element
	 */
	public HeaderElement(List<Element> children, HeaderLevel headerLevel,
			Map<String, String> properties) {
		super(children, properties);
		this.level = headerLevel;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * This method passes the following event
	 * <ul> 
	 * 	<li>{@link EndHeaderEvent} </li>
	 * </ul>
	 * 
	 */
	@Override
	public void afterElement(Listener listener) {
		EndHeaderEvent e = new EndHeaderEvent(getHeaderLevel(),
				getAllProperties());
		listener.onEvent(e);
	}

	/**
	 * {@inheritDoc}
	 * * This method passes the following event
	 * <ul> 
	 * 	<li>{@link StartHeaderEvent} </li>
	 * </ul>
	 * 
	 */
	@Override
	public void beforeElement(Listener listener) {
		StartHeaderEvent e = new StartHeaderEvent(getHeaderLevel(),
				getAllProperties());
		listener.onEvent(e);
	}

	/**
	 * 
	 * @return the level of the header. For more information, see
	 *         {@link HeaderLevel}
	 *  <p>
	 * This property is immutable and thread-safe
	 * </p>
	 */
	public HeaderLevel getHeaderLevel() {
	
			return level;
	

	}

	

}
